package com.lfs.market.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.BeanCopier;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lfs.market.constants.PayConstant;
import com.lfs.market.constants.ProductConstant;
import com.lfs.market.exception.ServiceException;
import com.lfs.market.mapper.ProductInfoMapper;
import com.lfs.market.model.R;
import com.lfs.market.model.dto.ProductInfoDto;
import com.lfs.market.model.dto.ProductInfoPageDto;
import com.lfs.market.model.dto.SystemAddProductDto;
import com.lfs.market.model.dto.SystemProductInfoPageDto;
import com.lfs.market.model.entity.*;
import com.lfs.market.model.enums.ResultCode;
import com.lfs.market.model.vo.*;
import com.lfs.market.service.*;
import com.lfs.market.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class ProductInfoServiceImpl extends ServiceImpl<ProductInfoMapper, ProductInfo> implements ProductInfoService {
    @Autowired
    private UserService userService;
    @Autowired
    private ProductTypeService productTypeService;
    @Autowired
    private ProductCollectService productCollectService;
    @Autowired
    private ProductVoucherService productVoucherService;

    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private OrdersService ordersService;

    @Autowired
    private SystemUserService systemUserService;

    @Autowired
    private ProductOrderService productOrderService;

    @Override
    public R createProductInfo(ProductInfoDto dto) {
        ProductInfo productInfo = BeanUtil.toBean(dto, ProductInfo.class);
        if (StrUtil.isNotEmpty(dto.getType())) {
            ProductType productType = productTypeService.lambdaQuery().eq(ProductType::getTypeCode, dto.getType()).one();
            if (!BeanUtil.isEmpty(productType)) {
                productInfo.setTypeCode(productType.getTypeCode());
                productInfo.setTypeName(productType.getTypeName());
            }
        }
        productInfo.setPrice(dto.getPrice());
        productInfo.setOriginalPrice(dto.getOriginalPrice());
        productInfo.setStatus(ProductConstant.UN_REVIEWED);
        productInfo.setLikeCount(0);
        productInfo.setUserId(StpUtil.getLoginIdAsString());
        productInfo.setCreateTime(new Date());
        productInfo.setUpdateTime(new Date());
        productInfo.setPostType(dto.getPostType());

        //只有自提的时候才有地址
        if (dto.getPostType() == 1) {
            productInfo.setAddress(dto.getAddress());
        }
        boolean save = save(productInfo);
        if (!save) throw new ServiceException(ResultCode.SaveError);
        return R.ok();
    }

    @Override
    public List<ProductInfoPageVo> getProductList(ProductInfoPageDto pageDto) {
        int days = 1;
        if (StrUtil.isNotEmpty(pageDto.getSelectedTime())) {
            days = Integer.parseInt(pageDto.getSelectedTime());
        }

        Date endDate = new Date();
        Date startDate = new Date(endDate.getTime() - (long) days * 24 * 60 * 60 * 1000);
        Page<ProductInfo> page = lambdaQuery()
                .eq(StrUtil.isNotEmpty(pageDto.getTypeCode()), ProductInfo::getTypeCode, pageDto.getTypeCode())
                .eq(ProductInfo::getStatus, ProductConstant.PUBLISH)
                .between(StrUtil.isNotEmpty(pageDto.getSelectedTime()), ProductInfo::getCreateTime, startDate, endDate)
                .and(StrUtil.isNotEmpty(pageDto.getKey()), wrapper -> {
                    wrapper.like(StrUtil.isNotEmpty(pageDto.getKey()), ProductInfo::getTitle, pageDto.getKey());
                })
                .orderByDesc(ProductInfo::getCreateTime)
                .page(new Page<>(pageDto.getPageNumber(), pageDto.getPageSize()));
        List<ProductInfo> records = page.getRecords();
        List<ProductInfoPageVo> voList = records.stream().map(item -> {
            User user = userService.getById(item.getUserId());
            ProductInfoPageVo vo = BeanUtil.toBean(item, ProductInfoPageVo.class);
            if (!BeanUtil.isEmpty(user)) {
                vo.setAvatar(user.getAvatar());
            }
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    /**
     * 执行这个方法说明开始价格和结束价格一定有一个不为空
     *
     * @param pageDto
     * @return
     */
    @Override
    public List<ProductInfoPageVo> getPriceProductList(ProductInfoPageDto pageDto) {
        BigDecimal startPrice = new BigDecimal(0);
        BigDecimal endPrice = new BigDecimal(0);
        if (pageDto.getStartPrice() != null) {
            startPrice = pageDto.getStartPrice();
        }
        if (pageDto.getEndPrice() != null) {
            endPrice = pageDto.getEndPrice();
        }

        int days = 1;
        if (StrUtil.isNotEmpty(pageDto.getSelectedTime())) {
            days = Integer.parseInt(pageDto.getSelectedTime());
        }

        Date endDate = new Date();
        Date startDate = new Date(endDate.getTime() - (long) days * 24 * 60 * 60 * 1000);
        Page<ProductInfo> page = lambdaQuery()
                .eq(StrUtil.isNotEmpty(pageDto.getTypeCode()), ProductInfo::getTypeCode, pageDto.getTypeCode())
                .eq(ProductInfo::getStatus, ProductConstant.PUBLISH)
                .between(StrUtil.isNotEmpty(pageDto.getSelectedTime()), ProductInfo::getCreateTime, startDate, endDate)

                // 当开始的价格与结束的价格都不为空时执行，这时startPrice和endPrice不会为0
                .between(pageDto.getStartPrice() != null && pageDto.getEndPrice() != null,
                        ProductInfo::getPrice,
                        startPrice,
                        endPrice
                )
                //大于等于  startPrice <= 条件：结束价格为空，说明开始价格不为空，则我们判断大于等于开始价格的情况
                .ge(endPrice.compareTo(BigDecimal.ZERO) == 0, ProductInfo::getPrice, startPrice)
                //小于等于  endPrice >= 条件：开始价格为空，说明结束价格不为空，则我们判断小于等于结束价格的情况
                .le(startPrice.compareTo(BigDecimal.ZERO) == 0, ProductInfo::getPrice, endPrice)
                .and(StrUtil.isNotEmpty(pageDto.getKey()), wrapper -> {
                    wrapper.like(StrUtil.isNotEmpty(pageDto.getKey()), ProductInfo::getTitle, pageDto.getKey());
                })
                .orderByDesc(ProductInfo::getCreateTime)
                .page(new Page<>(pageDto.getPageNumber(), pageDto.getPageSize()));
        List<ProductInfo> records = page.getRecords();
        List<ProductInfoPageVo> voList = records.stream().map(item -> {
            User user = userService.getById(item.getUserId());
            ProductInfoPageVo vo = BeanUtil.toBean(item, ProductInfoPageVo.class);
            if (!BeanUtil.isEmpty(user)) {
                vo.setAvatar(user.getAvatar());
            }
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    /**
     *
     */
    @Override
    public UserStatVo getUserStat() {
        UserStatVo userStatVo = new UserStatVo();
        String userId = StpUtil.getLoginIdAsString();

        //用户已发布
        List<ProductInfo> publishList = lambdaQuery().eq(ProductInfo::getUserId, userId).list();
        int publishSize = publishList.size();
        //
        userStatVo.setPublish(publishSize);
        return userStatVo;
    }

    /**
     * 商品卖出
     *
     * @param productId
     * @return
     */
    @Override
    public void productSoldOut(String productId) {
        ProductInfo productInfo = baseMapper.selectById(productId);
        productInfo.setStatus(ProductConstant.SALE);
        baseMapper.updateById(productInfo);
    }

    /**
     * 获取商品订单信息
     *
     * @return
     */
    @Override
    public ProductOrderStatVo getProductOrderList() {
        String userId = StpUtil.getLoginIdAsString();
        // 1、发布 即统计所有当前用户下的商品 即使下架也包括在内
        List<ProductInfo> publishList = productInfoService.lambdaQuery().eq(ProductInfo::getUserId, userId).list();

        // 2、卖出
        List<Orders> sellList = ordersService.lambdaQuery().eq(Orders::getProductUserId, userId).list();

        // 3、买入
        List<Orders> buyList = ordersService.lambdaQuery().eq(Orders::getUserId, userId).list();

        List<ProductCollect> collectList = productCollectService.lambdaQuery().eq(ProductCollect::getUserId, userId).list();

        ProductOrderStatVo statVo = new ProductOrderStatVo();
        statVo.setPublishSize(publishList.size());
        statVo.setSellSize(sellList.size());
        statVo.setBuySize(buyList.size());
        statVo.setCollectSize(collectList.size());
        return statVo;
    }

    /**
     * 查询已买入的商品信息
     *
     * @return
     */
    @Override
    public List<BuyProductVo> getMyBuy() {
        String userId = StpUtil.getLoginIdAsString();
        List<BuyProductVo> productInfoVo = new ArrayList<>();

        //获取支付成功的订单信息
        List<Orders> orderList = ordersService.successPayOrder(userId);
        List<String> productIdList = orderList.stream().map(Orders::getProductId).collect(Collectors.toList());

        for (String productId : productIdList) {
            ProductInfo productInfo = productInfoService.getById(productId);
            Orders orders = ordersService.lambdaQuery()
                    .eq(Orders::getProductId, productId)
                    .eq(Orders::getPaymentStatus, PayConstant.PAYMENT_SUCCESS)
                    .one();

            BuyProductVo buyProductInfo = BeanCopyUtils.copyBean(productInfo, BuyProductVo.class);
            buyProductInfo.setPaymentStatus(orders.getPaymentStatus());
            buyProductInfo.setOrderStatus(orders.getStatus());
            buyProductInfo.setOrderNo(orders.getOrderNo());
            buyProductInfo.setReceiveAddress(orders.getReceiveAddress());
            productInfoVo.add(buyProductInfo);
        }
        return productInfoVo;
    }

    /**
     * 查询已经卖出的商品信息
     *
     * @return
     */
    @Override
    public List<SellProductVo> getMySell() {
        String userId = StpUtil.getLoginIdAsString();
        List<SellProductVo> productInfoVo = new ArrayList<>();
        // 查询当前用户卖出的商品，就要查询订单中，商品的卖出用户
        List<Orders> orderList = ordersService.getOrderBySell(userId);

        List<String> productIdList = orderList.stream().map(Orders::getProductId).collect(Collectors.toList());

        for (String productId : productIdList) {
            ProductInfo productInfo = productInfoService.getById(productId);
            Orders orders = ordersService.lambdaQuery()
                    .eq(Orders::getProductId, productId)
                    .eq(Orders::getPaymentStatus, PayConstant.PAYMENT_SUCCESS)
                    .one();

            SellProductVo sellProductInfo = BeanCopyUtils.copyBean(productInfo, SellProductVo.class);
            sellProductInfo.setPaymentStatus(orders.getPaymentStatus());
            sellProductInfo.setOrderStatus(orders.getStatus());
            sellProductInfo.setOrderNo(orders.getOrderNo());
            sellProductInfo.setReceiveAddress(orders.getReceiveAddress());
            productInfoVo.add(sellProductInfo);
        }
        return productInfoVo;
    }

    /**
     * 查询订单信息
     *
     * @return
     */
    @Override
    public List<OrderProductVo> getMyOrder() {
        String userId = StpUtil.getLoginIdAsString();
        List<OrderProductVo> productInfoVo = new ArrayList<>();
        List<Orders> ordersList = ordersService.lambdaQuery()
                .eq(Orders::getUserId, userId)
                .list();
        for (Orders orders : ordersList) {
            ProductInfo productInfo = productInfoService.getById(orders.getProductId());
            OrderProductVo orderProductVo = BeanCopyUtils.copyBean(productInfo, OrderProductVo.class);
            orderProductVo.setPaymentStatus(orders.getPaymentStatus());
            orderProductVo.setOrderStatus(orders.getStatus());
            orderProductVo.setOrderNo(orders.getOrderNo());
            orderProductVo.setReceiveAddress(orders.getReceiveAddress());
            productInfoVo.add(orderProductVo);
        }
        return productInfoVo;
    }

    //直接查询没有价格条件
    @Override
    public List<ProductInfoPageVo> getPriceProduct(ProductInfoPageDto pageDto) {
        int days = 1;
        Date endDate = new Date();
        Date startDate = new Date(endDate.getTime() - (long) days * 24 * 60 * 60 * 1000);
        Page<ProductInfo> page = lambdaQuery()
                .eq(StrUtil.isNotEmpty(pageDto.getTypeCode()), ProductInfo::getTypeCode, pageDto.getTypeCode())
                .eq(ProductInfo::getStatus, ProductConstant.PUBLISH)
                .between(StrUtil.isNotEmpty(pageDto.getSelectedTime()), ProductInfo::getCreateTime, startDate, endDate)
                .and(StrUtil.isNotEmpty(pageDto.getKey()), wrapper -> {
                    wrapper.like(StrUtil.isNotEmpty(pageDto.getKey()), ProductInfo::getTitle, pageDto.getKey());
                })
                .orderByDesc(ProductInfo::getCreateTime)
                .page(new Page<>(pageDto.getPageNumber(), pageDto.getPageSize()));
        List<ProductInfo> records = page.getRecords();
        List<ProductInfoPageVo> voList = records.stream().map(item -> {
            User user = userService.getById(item.getUserId());
            ProductInfoPageVo vo = BeanUtil.toBean(item, ProductInfoPageVo.class);
            if (!BeanUtil.isEmpty(user)) {
                vo.setAvatar(user.getAvatar());
            }
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    //查询两个价格之间的商品
    @Override
    public List<ProductInfoPageVo> getPriceBetweenProduct(ProductInfoPageDto pageDto) {
        int days = 1;
        if (StrUtil.isNotEmpty(pageDto.getSelectedTime())) {
            days = Integer.parseInt(pageDto.getSelectedTime());
        }
        Date endDate = new Date();
        Date startDate = new Date(endDate.getTime() - (long) days * 24 * 60 * 60 * 1000);
        Page<ProductInfo> page = lambdaQuery()
                .eq(StrUtil.isNotEmpty(pageDto.getTypeCode()), ProductInfo::getTypeCode, pageDto.getTypeCode())
                .eq(ProductInfo::getStatus, ProductConstant.PUBLISH)
                .between(StrUtil.isNotEmpty(pageDto.getSelectedTime()), ProductInfo::getCreateTime, startDate, endDate)
                // 当开始的价格与结束的价格都不为空时执行，这时startPrice和endPrice不会为0
                .between(pageDto.getStartPrice() != null && pageDto.getEndPrice() != null,
                        ProductInfo::getPrice,
                        pageDto.getStartPrice(),
                        pageDto.getEndPrice()
                )
                .and(StrUtil.isNotEmpty(pageDto.getKey()), wrapper -> {
                    wrapper.like(StrUtil.isNotEmpty(pageDto.getKey()), ProductInfo::getTitle, pageDto.getKey());
                })
                .orderByDesc(ProductInfo::getCreateTime)
                .page(new Page<>(pageDto.getPageNumber(), pageDto.getPageSize()));
        List<ProductInfo> records = page.getRecords();
        List<ProductInfoPageVo> voList = records.stream().map(item -> {
            User user = userService.getById(item.getUserId());
            ProductInfoPageVo vo = BeanUtil.toBean(item, ProductInfoPageVo.class);
            if (!BeanUtil.isEmpty(user)) {
                vo.setAvatar(user.getAvatar());
            }
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    /**
     * 查询开始价格往后的商品
     *
     * @param pageDto
     * @return
     */
    @Override
    public List<ProductInfoPageVo> getStartPriceProduct(ProductInfoPageDto pageDto) {
        int days = 1;
        if (StrUtil.isNotEmpty(pageDto.getSelectedTime())) {
            days = Integer.parseInt(pageDto.getSelectedTime());
        }
        Date endDate = new Date();
        Date startDate = new Date(endDate.getTime() - (long) days * 24 * 60 * 60 * 1000);
        Page<ProductInfo> page = lambdaQuery()
                .eq(StrUtil.isNotEmpty(pageDto.getTypeCode()), ProductInfo::getTypeCode, pageDto.getTypeCode())
                .eq(ProductInfo::getStatus, ProductConstant.PUBLISH)
                .between(StrUtil.isNotEmpty(pageDto.getSelectedTime()), ProductInfo::getCreateTime, startDate, endDate)
                // 当开始的价格与结束的价格都不为空时执行，这时startPrice和endPrice不会为0
                .ge(ProductInfo::getPrice, pageDto.getStartPrice())
                .and(StrUtil.isNotEmpty(pageDto.getKey()), wrapper -> {
                    wrapper.like(StrUtil.isNotEmpty(pageDto.getKey()), ProductInfo::getTitle, pageDto.getKey());
                })
                .orderByDesc(ProductInfo::getCreateTime)
                .page(new Page<>(pageDto.getPageNumber(), pageDto.getPageSize()));
        List<ProductInfo> records = page.getRecords();
        List<ProductInfoPageVo> voList = records.stream().map(item -> {
            User user = userService.getById(item.getUserId());
            ProductInfoPageVo vo = BeanUtil.toBean(item, ProductInfoPageVo.class);
            if (!BeanUtil.isEmpty(user)) {
                vo.setAvatar(user.getAvatar());
            }
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    /**
     * 查询小于等于EndPrice的商品
     *
     * @param pageDto
     * @return
     */
    @Override
    public List<ProductInfoPageVo> getEndPriceProduct(ProductInfoPageDto pageDto) {
        int days = 1;
        if (StrUtil.isNotEmpty(pageDto.getSelectedTime())) {
            days = Integer.parseInt(pageDto.getSelectedTime());
        }
        Date endDate = new Date();
        Date startDate = new Date(endDate.getTime() - (long) days * 24 * 60 * 60 * 1000);
        Page<ProductInfo> page = lambdaQuery()
                .eq(StrUtil.isNotEmpty(pageDto.getTypeCode()), ProductInfo::getTypeCode, pageDto.getTypeCode())
                .eq(ProductInfo::getStatus, ProductConstant.PUBLISH)
                .between(StrUtil.isNotEmpty(pageDto.getSelectedTime()), ProductInfo::getCreateTime, startDate, endDate)
                .le(ProductInfo::getPrice, pageDto.getEndPrice())
                .and(StrUtil.isNotEmpty(pageDto.getKey()), wrapper -> {
                    wrapper.like(StrUtil.isNotEmpty(pageDto.getKey()), ProductInfo::getTitle, pageDto.getKey());
                })
                .orderByDesc(ProductInfo::getCreateTime)
                .page(new Page<>(pageDto.getPageNumber(), pageDto.getPageSize()));
        List<ProductInfo> records = page.getRecords();
        List<ProductInfoPageVo> voList = records.stream().map(item -> {
            User user = userService.getById(item.getUserId());
            ProductInfoPageVo vo = BeanUtil.toBean(item, ProductInfoPageVo.class);
            if (!BeanUtil.isEmpty(user)) {
                vo.setAvatar(user.getAvatar());
            }
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    @Override
    public Integer getTodayNewProductsCount() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String today = sdf.format(new Date());
        return baseMapper.getTodayNewProductsCount(today);
    }

    @Override
    public Integer getMonthNewProductsCount() {
        return baseMapper.getMonthNewProductsCount();
    }

    /**
     * 查询统计商品数据
     *
     * @return
     */
    @Override
    public Map getCountData() {
        HashMap<Object, Object> map = new HashMap<>();
        // 本日订单数量
        Integer dailyOrder = ordersService.getDailyOrder();

        // 今日销售额
        BigDecimal salesToday = ordersService.getSalesToday();

        // 本日新增
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String today = sdf.format(new Date());
        Integer todayNewProductsCount = baseMapper.getTodayNewProductsCount(today);

        // 本月订单数量
        Integer monthOrder = ordersService.getMonthOrder();

        // 本月销售额
        BigDecimal salesMonth = ordersService.getSalesMonth();

        //本月新增
        Integer monthNewProductsCount = baseMapper.getMonthNewProductsCount();
        map.put("dailyOrder", dailyOrder);
        map.put("salesToday", salesToday);
        map.put("todayNewProductsCount", todayNewProductsCount);
        map.put("monthOrder", monthOrder);
        map.put("salesMonth", salesMonth);
        map.put("monthNewProductsCount", monthNewProductsCount);
        return map;
    }

    /**
     * 创建商品
     *
     * @param dto
     * @return
     */
    @Override
    public R addProduct(SystemAddProductDto dto) {
        ProductInfo productInfo = BeanUtil.toBean(dto, ProductInfo.class);
/*        if (StrUtil.isNotEmpty(dto.getTypeCode())) {
            ProductType productType = productTypeService.lambdaQuery().eq(ProductType::getTypeCode, dto.getTypeCode()).one();
            if (!BeanUtil.isEmpty(productType)) {
                productInfo.setTypeCode(productType.getTypeCode());
                productInfo.setTypeName(productType.getTypeName());
            }
        }*/
        productInfo.setTypeCode(dto.getTypeCode());
        productInfo.setTypeName(dto.getTypeName());
        productInfo.setPrice(dto.getPrice());
        productInfo.setOriginalPrice(dto.getOriginalPrice());
        productInfo.setStatus(ProductConstant.PUBLISH);
        productInfo.setLikeCount(0);
        productInfo.setUserId(StpUtil.getLoginIdAsString());
        productInfo.setCreateTime(new Date());
        productInfo.setUpdateTime(new Date());
        //管理员创建无地址
        productInfo.setAddress("自提");
        boolean save = save(productInfo);
        if (!save) throw new ServiceException(ResultCode.SaveError);
        return R.ok();
    }

    /**
     * 根据ids删除商品信息
     *
     * @param ids
     */
    @Override
    public R deleteProductInfo(List<String> ids) {
        LambdaQueryWrapper<ProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ProductInfo::getId, ids);
        remove(wrapper);
        return R.ok();
    }

    /**
     * 编辑商品信息
     *
     * @param productDto
     * @return
     */
    @Override
    public R editProduct(SystemAddProductDto productDto) {
        ProductInfo productInfo = BeanUtil.toBean(productDto, ProductInfo.class);
        updateById(productInfo);
        return R.ok();
    }

    /**
     * 动态列表
     *
     * @return
     */
    @Override
    public List<ProductInfoTrendVo> active() {

        List<ProductInfo> myProductList = productInfoService.getMyProductInfoList();
        List<ProductInfoTrendVo> publish = myProductList.stream().map(item -> {
            ProductInfoTrendVo bean = BeanUtil.toBean(item, ProductInfoTrendVo.class);
            bean.setType("publish");
            return bean;
        }).collect(Collectors.toList());

        List<ProductOrder> myBuyOrder = productOrderService.getMyBuyOrder();
        List<ProductInfoTrendVo> buy = myBuyOrder.stream().map(item -> {
            ProductInfo productInfo = productInfoService.getById(item.getProductId());
            ProductInfoTrendVo bean = BeanUtil.toBean(productInfo, ProductInfoTrendVo.class);
            bean.setCreateTime(item.getCreateTime());
            bean.setType("buy");
            return bean;
        }).collect(Collectors.toList());

        List<ProductOrder> mySellOrder = productOrderService.getMySellOrder();
        List<ProductInfoTrendVo> sell = mySellOrder.stream().map(item -> {
            ProductInfo productInfo = productInfoService.getById(item.getProductId());
            ProductInfoTrendVo bean = BeanUtil.toBean(productInfo, ProductInfoTrendVo.class);
            bean.setType("sell");
            bean.setCreateTime(item.getCreateTime());
            return bean;
        }).collect(Collectors.toList());
        publish.addAll(buy);
        publish.addAll(sell);

        return publish;
    }


    /**
     * 查询商品信息
     *
     * @param productId
     * @return
     */
    @Override
    public ProductInfoDetailVo getProductInfo(String productId) {
        ProductInfo productInfo = getById(productId);
        if (BeanUtil.isEmpty(productInfo)) throw new ServiceException(ResultCode.NotFindError);
        ProductInfoDetailVo productInfoDetailVo = BeanUtil.toBean(productInfo, ProductInfoDetailVo.class);
        User user = userService.getById(productInfo.getUserId());
        productInfoDetailVo.setUserInfo(user);
        return productInfoDetailVo;
    }

    /**
     * 获取已经发布的商品
     *
     * @return
     */
    @Override
    public List<ProductInfo> getMyProductInfoList() {
        String userId = StpUtil.getLoginIdAsString();
        List<ProductInfo> list = lambdaQuery()
                .eq(ProductInfo::getUserId, userId)
                //没有下架时
                .ne(ProductInfo::getStatus, ProductConstant.SOLD_OUT)
                .orderByDesc(ProductInfo::getCreateTime).list();
        return list;
    }

    /**
     * 想要人数+1
     *
     * @param productId
     * @return
     */
    @Override
    public void createLikeCount(String productId) {
        ProductInfo productInfo = getById(productId);
        if (BeanUtil.isEmpty(productInfo)) throw new ServiceException(ResultCode.NotFindError);
        Integer likeCount = productInfo.getLikeCount();
        productInfo.setLikeCount(likeCount + 1);
        boolean update = updateById(productInfo);
        if (!update) throw new ServiceException(ResultCode.UpdateError);
    }

    @Override
    public Page getProductInfoList(SystemProductInfoPageDto dto) {
        Page<ProductInfo> page = lambdaQuery()
                .eq(StrUtil.isNotEmpty(dto.getStatus()), ProductInfo::getStatus, dto.getStatus())
                .like(StrUtil.isNotEmpty(dto.getKey()), ProductInfo::getTitle, dto.getKey()).or()
                .like(StrUtil.isNotEmpty(dto.getKey()), ProductInfo::getTypeName, dto.getKey())
                .ne(ProductInfo::getStatus, 10)
                .orderByDesc(ProductInfo::getCreateTime)
                .page(new Page<>(dto.getPageNumber(), dto.getPageSize()));
        Page<ProductInfoVoucherVo> resultPage = copyPage(page, ProductInfoVoucherVo.class);
        List<ProductInfoVoucherVo> records = resultPage.getRecords();
        for (ProductInfoVoucherVo vo : records) {
            ProductVoucher one = productVoucherService.lambdaQuery().eq(ProductVoucher::getProductId, vo.getId()).one();
            vo.setProductVoucher(one);
        }
        return resultPage;
    }

    public static <T> Page<T> copyPage(Page sPage, Class<T> tClass) {
        Page<T> tPage = new Page();
        tPage.setPages(sPage.getPages());
        tPage.setCurrent(sPage.getCurrent());
        tPage.setSize(sPage.getSize());
        tPage.setTotal(sPage.getTotal());
        List<T> tList = new ArrayList();
        Iterator var4 = sPage.getRecords().iterator();

        while (var4.hasNext()) {
            Object record = var4.next();
            tList.add(toBean(record, tClass));
        }

        tPage.setRecords(tList);
        return tPage;
    }

    public static <T> T toBean(Object source, Class<T> clazz) {
        T target = ReflectUtil.newInstance(clazz, new Object[0]);
        copyProperties(source, target);
        return target;
    }

    public static void copyProperties(Object source, Object target) {
        copyProperties(source, target, CopyOptions.create());
    }

    public static void copyProperties(Object source, Object target, CopyOptions copyOptions) {
        if (null == copyOptions) {
            copyOptions = new CopyOptions();
        }

        BeanCopier.create(source, target, copyOptions).copy();
    }

    /**
     * 根据id查询商品详情
     *
     * @param id
     * @return
     */
    @Override
    public Map getDetail(String id) {
        ProductInfo productInfo = getById(id);
        if (BeanUtil.isEmpty(productInfo)) throw new ServiceException(ResultCode.NotFindError);
        String userId = productInfo.getUserId();

        SystemUser systemUser = systemUserService.getById(userId);

        //判断是不是管理员创建的商品：若不是管理员创建正常查询普通用户的信息
        User user = null;
        if (BeanUtil.isEmpty(systemUser)) {
            user = userService.getById(productInfo.getUserId());
        }

//        if (BeanUtil.isEmpty(user)) throw new ServiceException(ResultCode.NotFindError);
        HashMap<Object, Object> map = new HashMap<>();
        map.put("productInfo", productInfo);
        map.put("user", user);
        return map;
    }

    /**
     * 我的收藏
     *
     * @return
     */
    @Override
    public List<ProductInfo> getMyProductCollectInfo() {
        String userId = StpUtil.getLoginIdAsString();
        List<ProductCollect> collectList = productCollectService.lambdaQuery().eq(ProductCollect::getUserId, userId).list();
        List<ProductInfo> collect1 = collectList.stream().map(collect -> {
            ProductInfo productInfo = getById(collect.getProductId());
            ProductVoucher one = productVoucherService.lambdaQuery().eq(ProductVoucher::getProductId, productInfo.getId()).one();
            if (!BeanUtil.isEmpty(one)) {
                productInfo.setProductVoucher(one);
            }
            return productInfo;
        }).collect(Collectors.toList());
        return collect1;
    }

    /**
     * 商品审核通过
     *
     * @param id
     * @return
     */
    @Override
    public void passProduct(String id) {
        ProductInfo productInfo = getById(id);
        if (BeanUtil.isEmpty(productInfo)) throw new ServiceException(ResultCode.NotFindError);
        if (productInfo.getStatus() != 1) throw new ServiceException(ResultCode.ValidateError);
        productInfo.setStatus(ProductConstant.PUBLISH);
        boolean update = updateById(productInfo);
        if (!update) throw new ServiceException(ResultCode.UpdateError);

    }

    @Override
    public Long getTodayCount() {
        //获取今日0点开始时间
        LocalDateTime startDay = LocalDate.now().atStartOfDay();
        long startTime = startDay.toEpochSecond(ZoneOffset.UTC) * 1000;
        long endTime = new Date().getTime();
        Long count = lambdaQuery().between(ProductInfo::getCreateTime, startTime, endTime).count();
        return count;
    }

    @Override
    public Long getMonthCount() {
        LocalDate now = LocalDate.now();
        LocalDateTime startOfMonth = now.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay();
        long startTime = startOfMonth.toEpochSecond(ZoneOffset.UTC) * 1000;
        long endTime = new Date().getTime();
        Long count = lambdaQuery().between(ProductInfo::getCreateTime, startTime, endTime).count();
        return count;
    }

    /**
     * 商品审核失败
     *
     * @param id
     * @return
     */
    @Override
    public void failProduct(String id) {
        ProductInfo productInfo = getById(id);
        if (BeanUtil.isEmpty(productInfo)) throw new ServiceException(ResultCode.NotFindError);
        if (productInfo.getStatus() != 1) throw new ServiceException(ResultCode.ValidateError);
        productInfo.setStatus(2);
        boolean update = updateById(productInfo);
        if (!update) throw new ServiceException(ResultCode.UpdateError);
    }

    /**
     * 下架商品
     *
     * @param id
     * @return
     */
    @Override
    public void downProduct(String id) {
        ProductInfo productInfo = getById(id);
        if (BeanUtil.isEmpty(productInfo)) throw new ServiceException(ResultCode.NotFindError);
        if (!productInfo.getStatus().equals(ProductConstant.PUBLISH))
            throw new ServiceException(ResultCode.ValidateError);
        productInfo.setStatus(2);
        boolean update = updateById(productInfo);
        if (!update) throw new ServiceException(ResultCode.UpdateError);
    }


}
